<?php
/**
 * 工资核算控制器
 */

namespace app\admin\controller;

use app\common\model\Attendance;
use app\common\model\BasicSalary;
use app\common\model\Commission;
use app\common\model\Department;
use app\common\model\Insure;
use app\common\model\Performance;
use app\common\model\Staff;
use think\Db;
use think\request;
use app\common\model\SalaryLog;

use app\common\validate\SalaryLogValidate;
use function GuzzleHttp\Psr7\str;

class SalaryLogController extends Controller
{

    //列表
    public function index(Request $request, SalaryLog $salaryLog, BasicSalary $basicSalary, Staff $staff)
    {
        $param = $request->param();
        if (isset($param['salary_time'])) {
            $param['salary_time'] = strtotime($param['salary_time']);
        }
        $where1 = '';
        $where2 = '';
        //字段条件查询
        if (isset($param['salary_time']) && $param['salary_time'] != '') {
            $where1 .= ' and sa.salary_time=' . $param['salary_time'];
        }
        if (isset($param['staff_id']) && $param['staff_id'] != '') {
            $where2 .= ' and st.id=' . $param['staff_id'];
        }
        if (isset($param['department_id']) && $param['department_id'] != '') {
            $where2 .= ' and st.department_id=' . $param['department_id'];
        }

        $where1 .= ' and sa.delete_time =0';
        //排序
        $orderfield = isset($param['_order']) ? $param['_order'] : '';
        $by = $param['_by'] ?? '';
        $order = $orderfield . ' ' . $by;

        if ($order == ' ') {
            $order = 'department_id desc';
        }

        $model = Db::table('staff st')->field(
            '
                    sa.id as id,
                    st.id as staff_id,
                    st.name as staff_name,
                    st.hired_date as hired_date,
                    sa.insure_id as insure_id,
                    ins.insure as insure_name,
                    sa.base_merit_salary,
                    sa.position_level,
                    sa.salary_time,
                    st.department_id as department_id,
                    de.name as department_name,
                    de.type as department_type,
                    sa.basic_salary,
                    sa.manage_salary
                    ,sa.title_salary
                    ,sa.education_salary
                    ,sa.nightwork_salary
                    ,sa.payscale_salary
                    ,sa.secret_salary
                    ,sa.overtime_salary
                    ,sa.fulltime_salary
                    ,sa.phone_salary
                    ,sa.housing_salary
                    ,sa.other_salary
                    ,sa.base_merit_salary
                    ,sa.total_fixed_salary
                    ,sa.merit_salary
                    ,sa.real_total_fixed_salary
                    ,sa.commission
                    ,sa.live_commission
                    ,sa.bonus_penalty
                    ,sa.late_cut
                    ,sa.sick_allowance
                    ,sa.absence_leave_cut
                    ,sa.absenteeism_cut
                    ,sa.storage_time_cash
                    ,sa.travel_allowance
                    ,sa.travel_allowance
                    ,sa.other
                    ,sa.total_payoff
                    ,sa.social_security_salary
                    ,sa.deduct_social_money
                    ,sa.taxable_salary
                    ,sa.repair_miss_card_cut
                    ,sa.personal_tax
                    ,sa.after_tax_insurance_salary
                    ,sa.personal_pay
                    ,sa.real_pay
                    ,sa.cut_cash
                    ,sa.card_name
                    ,sa.card_num
                    ,sa.remarks
                    ,sa.info
                    ,sa.file
                    ,sa.status,
                    sa.email_status,
                    sa.update_time'

        )->join('salary_log sa', 'st.id=sa.staff_id' . $where1, 'left')->join('insure ins', 'st.insure_id=ins.id', 'left')->join('department de', 'st.department_id=de.id', 'left')->where('st.delete_time =0 and st.status=1' . $where2)->order($order);

        if (isset($param['export_data']) && $param['export_data'] == 1) {
            $header = ['ID', '姓名', '部门', '市场职级', '工资日期', '险种', '入职日期', '基本工资', '管理工资', '职称津贴', '学历津贴', '夜班津贴', '薪级津贴', '保密工资', '加班工资', '全勤奖', '通讯补助', '住房补贴', '其他补助', '绩效工资基数', '固定工资合计', '绩效工资', '实际固定工资', '提成', '直播提成', '奖惩', '迟到扣款', '病假补助', '事假扣款', '旷工扣款', '存班折现', '交通补助', '补/缺卡扣款', '其他项', '应发工资合计', '社保工资', '扣社保', '计税工资', '个人所得税', '税后险后工资', '个人发放', '实发工资', '扣款', '备注', '计算信息', '姓名1', '工资卡号', '附件', '状态', '邮件状态', '更新日期',];
            $body = [];
            $data = $model->select();
            foreach ($data as $item) {
                $record = [];
                $record['id'] = $item['id'];
                $record['staff_name'] = $item['staff_name'];
                $record['department_name'] = $item['department_name'];
                $record['position_level'] = $item['position_level'];
                $record['salary_time'] = date("Y-m", $item['salary_time']);
                $record['insurance'] = $item['insure_name'];
                $record['hired_date'] = $item['hired_date'];
                $record['basic_salary'] = $item['basic_salary'];
                $record['manage_salary'] = $item['manage_salary'];
                $record['title_salary'] = $item['title_salary'];
                $record['education_salary'] = $item['education_salary'];
                $record['nightwork_salary'] = $item['nightwork_salary'];
                $record['payscale_salary'] = $item['payscale_salary'];
                $record['secret_salary'] = $item['secret_salary'];
                $record['overtime_salary'] = $item['overtime_salary'];
                $record['fulltime_salary'] = $item['fulltime_salary'];
                $record['phone_salary'] = $item['phone_salary'];
                $record['housing_salary'] = $item['housing_salary'];
                $record['other_salary'] = $item['other_salary'];
                $record['base_merit_salary'] = $item['base_merit_salary'];
                $record['total_fixed_salary'] = $item['total_fixed_salary'];
                $record['merit_salary'] = $item['merit_salary'];
                $record['real_total_fixed_salary'] = $item['real_total_fixed_salary'];
                $record['commission'] = $item['commission'];
                $record['live_commission'] = $item['live_commission'];
                $record['bonus_penalty'] = $item['bonus_penalty'];
                $record['late_cut'] = $item['late_cut'];
                $record['sick_allowance'] = $item['sick_allowance'];
                $record['absence_leave_cut'] = $item['absence_leave_cut'];
                $record['absenteeism_cut'] = $item['absenteeism_cut'];
                $record['storage_time_cash'] = $item['storage_time_cash'];
                $record['travel_allowance'] = $item['travel_allowance'];
                $record['repair_miss_card_cut'] = $item['repair_miss_card_cut'];
                $record['other'] = $item['other'];
                $record['total_payoff'] = $item['total_payoff'];
                $record['social_security_salary'] = $item['social_security_salary'];
                $record['deduct_social_money'] = $item['deduct_social_money'];
                $record['taxable_salary'] = $item['taxable_salary'];
                $record['personal_tax'] = $item['personal_tax'];
                $record['after_tax_insurance_salary'] = $item['after_tax_insurance_salary'];
                $record['personal_pay'] = $item['personal_pay'];
                $record['real_pay'] = $item['real_pay'];
                $record['cut_cash'] = $item['cut_cash'];
                $record['remarks'] = $item['remarks'];
                $record['info'] = $item['info'];
                $record['card_name'] = $item['card_name'];
                $record['card_num'] = $item['card_num'];
                $record['file'] = $item['file'];
                $record['status'] = $item['status'] ? "启用" : "禁用";
                $record['email_status'] = $item['email_status'] ? "已发送" : "未发送";
                $record['update_time'] = date('Y-m-d H:i', $item['update_time']);

                $body[] = $record;
            }

            return $this->exportData($header, $body, date('Y-m', strtotime(date('Y-m-01') . " - 1 month")) . '工资-' . date('Y-m-d-H-i-s'));
        }

        $data = $model->paginate($this->admin['per_page'], false, ['query' => $request->get()]);
        //关键词，排序等赋值
        if (isset($param['department_id']) && !empty($param['department_id'])) {
            $demodel = Department::get($param['department_id']);
            $this->assign('department_list', $this->getSelectList($demodel, $param['department_id']));
        } else {
            $this->assign('department_list', $this->getSelectList(new Department));
        }
        //关键词，排序等赋值
        $this->assign($request->get());
        $this->assign([
            'departments' => Department::all(),
            'insure' => Insure::all(),
            'staff_list' => Staff::all(),
            'data' => $data,
            'page' => $data->render(),
            'total' => $data->total(),
        ]);
        return $this->fetch();
    }

    //添加
    public function add(Request $request, SalaryLog $model, SalaryLogValidate $validate)
    {
        if ($request->isPost()) {
            $param = $request->param();

            $validate_result = $validate->scene('add')->check($param);
            if (!$validate_result) {
                return error($validate->getError());
            }
            //处理附件上传
            if (!empty($_FILES['file']['name'][0])) {
                $attachment_file = new \app\common\model\Attachment;
                $file = $attachment_file->uploadMulti('file');
                if ($file) {
                    $param['file'] = $file;
                } else {
                    return error($attachment_file->getError());
                }
            }
            if (!isset($param['id']) || $param['id'] == '') {
                $result = $model::create($param);
            } elseif (isset($param['id']) && $param['id'] != '') {
                $result = $model->save($param, ['id', $param['id']]);
            }

            $url = URL_BACK;
            if (isset($param['_create']) && $param['_create'] == 1) {
                $url = URL_RELOAD;
            }

            return $result ? success('添加成功', $url) : error();
        }
        $param = $request->param();

        if (isset($param['staff_id']) && isset($param['salary_time']) && isset($param['department_id'])) {
            $data = $param;

            $parmodel = Department::where('id', $param['department_id'])->find();
            $this->assign([
                'department_list' => $this->getSelectList($parmodel, $param['department_id']),
                'data' => $data
            ]);

        } else {
            $this->assign([
                'department_list' => $this->getSelectList(new Department),
            ]);
        }

        $this->assign(['staff_list' => Staff::all()]);

        return $this->fetch();
    }

    //修改
    public function edit($id, Request $request, SalaryLog $model, SalaryLogValidate $validate)
    {
        $data = $model::where('id', $id)->with(['staff' => function ($query) {
            $query->with(['department']);
        }])->find();
        if ($request->isPost()) {
            $param = $request->param();
            $validate_result = $validate->scene('edit')->check($param);
            if (!$validate_result) {
                return error($validate->getError());
            }
            //处理附件上传
            if (!empty($_FILES['file']['name'][0])) {
                $attachment_file = new \app\common\model\Attachment;
                $file = $attachment_file->uploadMulti('file');
                if ($file) {
                    $param['file'] = $file;
                } else {
                    return error($attachment_file->getError());
                }
            }

            $result = $data->save($param);
            return $result ? success() : error();
        }
        if ($data->staff->department) {
            $this->assign(
                ['department_list' => $this->getSelectList($data->staff->department, $data->staff->department->id)]
            );
        } else {
            $this->assign([
                'department_list' => $this->getSelectList(new Department),
            ]);
        }

        $this->assign([
            'data' => $data,
            'staff_list' => Staff::all(['department_id' => $data->staff->department_id]),
        ]);
        return $this->fetch('add');
    }

    //删除
    public function del($id, SalaryLog $model)
    {
        if (count($model->noDeletionId) > 0) {
            if (is_array($id)) {
                if (array_intersect($model->noDeletionId, $id)) {
                    return error('ID为' . implode(',', $model->noDeletionId) . '的数据无法删除');
                }
            } else if (in_array($id, $model->noDeletionId)) {
                return error('ID为' . $id . '的数据无法删除');
            }
        }

        if ($model->softDelete) {
            $result = $model->whereIn('id', $id)->useSoftDelete('delete_time', time())->delete();
        } else {
            $result = $model->whereIn('id', $id)->delete();
        }

        return $result ? success('操作成功', URL_RELOAD) : error();
    }

    //启用
    public function enable($id, SalaryLog $model)
    {
        $result = $model->whereIn('id', $id)->update(['status' => 1]);
        return $result ? success('操作成功', URL_RELOAD) : error();
    }


    //禁用
    public function disable($id, SalaryLog $model)
    {
        $result = $model->whereIn('id', $id)->update(['status' => 0]);
        return $result ? success('操作成功', URL_RELOAD) : error();
    }

    //计算员工考勤生成工资
    public function compose(Request $request, Staff $staff, Performance $performance, BasicSalary $basicSalary, Commission $commission, Attendance $attendance, SalaryLog $salaryLog)
    {
        $param = $request->param();
        if (isset($param['staff_id']) && isset($param['salary_time'])) {
            $time = strtotime($param['salary_time']);
            //区别是否重新生成
            if (isset($param['id']) && $param['id'] == '') {
                $salaryLog = SalaryLog::where(['staff_id' => $param['staff_id'], 'salary_time' => $time])->find();
                //此月份已有工资信息
                if ($salaryLog) {
                    error('已经有此员工' . $param['salary_time'] . '的工资信息', URL_CURRENT, $salaryLog);
                }
            }

            //员工信息
            $staff = Staff::where(['id' => $param['staff_id'], 'status' => 1])->with('department')->find();
            if (!$staff) {
                error('没有此员工或被禁用');
            }

            //员工基本工资信息
            $basicSalary = BasicSalary::where(['staff_id' => $param['staff_id'], 'status' => 1])->find();
            if ($basicSalary) {
                $basicSalary = $basicSalary->toArray();
            } else {
                error('没有此员工基本工资或被禁用');
            }

            $basicSalary['info'] = "";//记录计算流程；
            //处理是否有实习期获得转正时间
            $full_salary_date = $staff->full_salary_date;//薪资转正日期
            $full_date = $staff->full_date;//转正日期
            $test_scale = $basicSalary['test_scale'];//实习工资比例
            $start = date('Y-m-01', strtotime($param['salary_time']));
            $end = date('Y-m-d', strtotime("$start +1 month -1 day"));
            $start_time = strtotime($start);
            $end_time = strtotime($end);
            //转正时间
            $full_salary_time = strtotime($full_salary_date);
            $full_time = strtotime($full_date);
            $flag = 1;
            //在实习期
            if ($full_salary_time >= $end_time) {
                $flag = $test_scale;
                $basicSalary['info'] .= '在实习期';
            }
            //不在实习期
            if ($full_salary_time < $start_time) {
                $flag = 1;
            }
            if ($full_salary_time < $end_time && $full_salary_time >= $start_time) {
                $flag = $test_scale;
                $test_day = date('d', $full_salary_time);
                $end_day = date('d', $end_time);
                $normal_day = $end_day - $test_day;
                $basicSalary['info'] .= "有实习工资" . $test_day . '天 ; ';
            }
            //当月转正
            if ($full_time < $end_time && $full_time >= $start_time) {
                $basicSalary['info'] .= '转正;';
            }

            $basicSalary['card_name'] = $staff->card_name;
            $basicSalary['card_num'] = $staff->card_num;
            //变量设置

            $basicSalary['salary_time'] = $time;
            $salaryPerHouse = 0;//员工每小时工资（动态绩效+固定部分）/24/8;
            $full_money = 0;//默认不扣全勤奖
            $basicSalary['insure_id'] = $staff->insure_id;
            //提成处理
            $commission = Commission::where(['staff_id' => $param['staff_id'], 'status' => 1, 'commission_time' => $time])->find();
            if ($commission) {
                $basicSalary['commission'] = $commission->total_commission;
                $basicSalary['info'] .= "提成=提成表合计{$basicSalary['commission']};   ";
                //提成备注
                $basicSalary['remarks'] .= '提成备注：' . ($commission->remarks ? $commission->remarks : '无') . ';';
            } else {
                //没有提成表信息
                $basicSalary['commission'] = 0;
                $basicSalary['info'] .= "没有提成表信息提成为0元;   ";
            }
            //绩效处理
            $performance = Performance::where(['staff_id' => $param['staff_id'], 'status' => 1, 'performance_time' => $time])->find();
            if ($performance) {

                $baseMeritSalary = $basicSalary['base_merit_salary'];
                $basicSalary['remarks'] .= "绩效备注：" . ($performance->remarks ? $performance->remarks : '无') . ';';
                $score = $performance->score;
                $departType = $staff->department->type;
                $inScore = \config('companyRules.in_department');
                $outScore = \config('companyRules.out_department');
                //验证绩效有效分数、验证
                if ($departType == 1) {
                    $score = $score >= $inScore ? $inScore : $score;
                } elseif ($departType == 2) {
                    $score = $score >= $outScore ? $outScore : $score;
                }
                //市场一部单独处理
                $departName = $staff->department->name;
                $hiredDate = $staff->hired_date;
                $date = date('Y-m-d', $time);
                $hiredDate = str_replace('-', '', $hiredDate);
                $date = str_replace('-', '', $date);
                //入职时间
                $hiredmonth = bcsub($date, $hiredDate, 2) / 100;

                if (strpos($departName, '市场一部') !== false && $score < 60 && $hiredmonth > 6) {
                    //入职超过六个月
                    $basicSalary['real_total_fixed_salary'] = $basicSalary['total_fixed_salary'] * $score / 100;

                    $basicSalary['info'] .= "市场一部入职6个月以上绩效60分一下,实际固定工资合计=固定工资合计（包含绩效）{$basicSalary['total_fixed_salary']}*绩效得分{$score}/100={$basicSalary['real_total_fixed_salary']};   ";
                } else {
                    $basicSalary['merit_salary'] = $baseMeritSalary * $score / 100;
                    $total_fixed_salary = $basicSalary['total_fixed_salary'];
                    $basicSalary['real_total_fixed_salary'] = ($total_fixed_salary - $baseMeritSalary + $basicSalary['merit_salary']) * $flag;//实习相应折扣
                    $basicSalary['info'] .= "绩效工资=绩效工资基数{$baseMeritSalary}*绩效评分{$score}={$basicSalary['merit_salary']}; ";

                    $basicSalary['info'] .= "实际固定工资为固定工资（{$basicSalary['total_fixed_salary']}-固定绩效{$basicSalary['base_merit_salary']}+实际绩效{$basicSalary['merit_salary']}）*{$flag}(是否实习) ={$basicSalary['real_total_fixed_salary']}; ";
                }

            } else {
                //没有绩效表的暂时按固定绩效算
                $basicSalary['merit_salary'] = $basicSalary['base_merit_salary'];
                $basicSalary['real_total_fixed_salary'] = $basicSalary['total_fixed_salary'] * $flag;//实习相应折扣。
                $basicSalary['info'] .= "没有{$param['salary_time']}绩效信息，实际固定工资=固定工资为{$basicSalary['real_total_fixed_salary']}; ";
                $basicSalary['info'] .= "没有{$param['salary_time']}绩效信息，绩效工资=绩效基本工资{$basicSalary['base_merit_salary']};   ";
            }

            //考勤处理(规则先写死，后期增加设置规则)
            $attendance = Attendance::where(['staff_id' => $param['staff_id'], 'status' => 1, 'attendance_time' => $time])->find();

            $basicSalary['sick_allowance'] = 0;//病假补助
            $basicSalary['late_cut'] = 0;//迟到扣款
            $basicSalary['absence_leave_cut'] = 0;//事假
            $basicSalary['absenteeism_cut'] = 0;//旷工
            $basicSalary['storage_time_cash'] = 0;//加班储存
            $basicSalary['total_payoff'] = 0; //应发工资合计
            $basicSalary['repair_miss_card_cut'] = 0;//补卡缺卡扣除
            $basicSalary['personal_pay'] = 0; //个户发放
            $basicSalary['real_pay'] = 0;//实发工资
            //未处理
            $basicSalary['travel_allowance'] = 0;//出差补助
            $basicSalary['live_commission'] = 0;//直播提成
            $basicSalary['bonus_penalty'] = 0;//奖惩
            $basicSalary['other'] = 0;//其他
            $basicSalary['cut_cash'] = 0;//扣款
            //员工工作天数、每天工作小时
            $staff_days = $staff->days_per_month;
            $staff_hours = $staff->hours_per_day;
            if ($attendance) {
                $attendance = $attendance->toArray();
                $basicSalary['position_level'] = $attendance['position_level'];
                //补卡第几次开始扣钱
                $repair_times_rule = \config('companyRules.repair_card_times_limit');
                $repair_card_times_hour = \config('companyRules.repair_card_times_hour');//补卡次数达到规定次数一次扣事假小时数
                $repair_times_max = \config('companyRules.repair_card_times_max');//补卡多少次扣全勤

                //扣全勤的情况  迟到情况处理：达到三次扣全勤奖
                if (!$attendance['is_full']) {
                    $full_money = 200;
                    $basicSalary['fulltime_salary'] = 0;
                    $real_total_fixed_salary = $basicSalary['real_total_fixed_salary'];
                    $basicSalary['real_total_fixed_salary'] = $real_total_fixed_salary - 200;
                    //缺勤时时薪计算先减200;
                    $salaryPerDays = $basicSalary['real_total_fixed_salary'] / $staff_days;
                    $salaryPerHouse = $basicSalary['real_total_fixed_salary'] / $staff_days / $staff_hours;
                    //计算存班时薪
                    $salaryPerHouse2 = $real_total_fixed_salary / $staff_days / $staff_hours;
                    $basicSalary['info'] .= "实际固定工资=固定工资{$real_total_fixed_salary}-全勤200={$basicSalary['real_total_fixed_salary']}，每小时工资=实际固定工资（包含当月绩效绩效）" . $basicSalary['real_total_fixed_salary'] . "/$staff_days/$staff_hours={$salaryPerHouse};   ";
                } else {
                    $salaryPerDays = $basicSalary['real_total_fixed_salary'] / $staff_days;
                    $salaryPerHouse = $basicSalary['real_total_fixed_salary'] / $staff_days / $staff_hours;
                    $salaryPerHouse2 = $basicSalary['real_total_fixed_salary'] / $staff_days / $staff_hours;
                }
                //检索迟到情况
                $late_rule_time_money = \config('companyRules.late_rule_time_money');//迟到规则
                $maxkey = count($late_rule_time_money) - 1;
                if ($attendance['late_time']) {
                    foreach ($attendance['late_time'] as $key => $value) {
                        foreach ($late_rule_time_money as $k => $v) {

                            if ($value <= $v['time']) {
                                //大于一小时按事假
                                if ($k < $maxkey) {
                                    $basicSalary['late_cut'] += $v['money'];
                                    $basicSalary['info'] .= "迟到扣款+{$v['money']}合计：{$basicSalary['late_cut']};   ";
                                } else {
                                    //超过60按事假扣
                                    //半小时为节点
                                    $hour1 = floor($value / 60);
                                    $mod = $value % 60;
                                    if ($mod <= 30) {
                                        $hour = $hour1 + 0.5;
                                    } else {
                                        $hour = $hour1 + 1;
                                    }
                                    $basicSalary['late_cut'] += $salaryPerHouse * $hour;
                                    $basicSalary['info'] .= "迟到时间超过一个小时事假扣款，迟到扣款+{$salaryPerHouse}*{$hour}迟到扣款合计{$basicSalary['late_cut']};   ";
                                }
                                break;
                            }
                        }
                    }
                }

                $sickAllowance = \config('companyRules.sick_leave_allowance_base');//病假补助基数

                //病假部分处理
                if ($attendance['sick_leave']) {
                    //病假补助2050*0.8/24/8
                    $basicSalary['sick_allowance'] = round($sickAllowance * 0.8 / $staff_hours / $staff_days * $attendance['sick_leave'], 2);
                    $basicSalary['info'] .= "病假补助=基数{$sickAllowance}*0.8/$staff_days/$staff_hours={$basicSalary['sick_allowance']};   ";
                    //事假扣款（病假部分）
                    $basicSalary['absence_leave_cut'] = $salaryPerHouse * $attendance['sick_leave'];
                    $basicSalary['info'] .= "事假扣款（病假部分）=每小时工资{$salaryPerHouse}*病假{$attendance['sick_leave']}小时={$basicSalary['absence_leave_cut']};   ";
                }

                //事假部分处理
                if ($attendance['absence_leave']) {
                    $basicSalary['absence_leave_cut'] += $salaryPerHouse * $attendance['absence_leave'];
                    $basicSalary['info'] .= "事假扣款（包含病假部分)=每小时工资{$salaryPerHouse}*事假{$attendance['absence_leave']}小时+病假扣款={$basicSalary['absence_leave_cut']};   ";
                }

                //旷工部分处理
                if ($attendance['absenteeism']) {
                    $basicSalary['absenteeism_cut'] = $salaryPerHouse * $attendance['absenteeism'] * 3;
                    $basicSalary['info'] .= "旷工扣款=每小时工资{$salaryPerHouse}*3*旷工{$attendance['absenteeism']}小时={$basicSalary['absenteeism_cut']};   ";
                }

                //存班情况处理（存班按不扣全勤奖计算）
                if ($attendance['storage_time']) {
                    $basicSalary['storage_time_cash'] = $salaryPerHouse2 * $attendance['storage_time'];
                    $basicSalary['info'] .= "存班折现=存班时间（时）{$attendance['storage_time']}*（未减全勤）每小时工资{$salaryPerHouse2}={$basicSalary['storage_time_cash']};   ";
                }

                if ($attendance['repair_card_times'] >= $repair_times_rule) {
                    $repair_times_hour = ($attendance['repair_card_times'] + 1 - $repair_times_rule) * $repair_card_times_hour;
                    $basicSalary['repair_miss_card_cut'] += $salaryPerHouse * $repair_times_hour;
                    $basicSalary['info'] .= "补卡{$attendance['repair_card_times']}次达到或超过规定次数{$repair_times_rule}每超过一次按事假{$repair_card_times_hour}小时计算，补卡扣款{$basicSalary['repair_miss_card_cut']};   ";
                }

                //区分内职市场扣款
                $departType = $staff->department->type;
                $in_miss_card_cut = config('companyRules.in_miss_card_cut');
                //缺卡情况缺卡一次按旷工一个小时算
                if ($attendance['miss_card_times']) {
                    if ($departType == 1) {
                        $basicSalary['repair_miss_card_cut'] += $salaryPerHouse * $in_miss_card_cut * $attendance['miss_card_times'];
                        $basicSalary['info'] .= "缺卡" . $attendance['miss_card_times'] . '次每次按旷工一小时计算，每小时工资' . $salaryPerHouse . "*$in_miss_card_cut*" . '次数' . $attendance['miss_card_times'] . ',补卡缺卡扣款+' . $salaryPerHouse * 3 * $attendance['miss_card_times'] . '合计：' . $basicSalary['repair_miss_card_cut'] . ";   ";
                    }

                    if ($departType == 2) {
                        if (isset($attendance['miss_card_cut'])) {
                            $miss_card_cut = $attendance['miss_card_cut'];
                        } else {
                            $miss_card_cut = config('companyRules.miss_card_cut');
                        }
                        $basicSalary['repair_miss_card_cut'] += $miss_card_cut * $attendance['miss_card_times'];
                        $basicSalary['info'] .= "缺卡" . $attendance['miss_card_times'] . '次每次扣款' . $miss_card_cut . ',补卡缺卡扣款+' . $miss_card_cut * $attendance['miss_card_times'] . '合计：' . $basicSalary['repair_miss_card_cut'] . ";   ";
                    }
                }
                //市场员工缺签到扣款处理
                if ($attendance['miss_sign_times'] && $departType == 2) {

                    if (isset($attendance['miss_sign_cut'])) {
                        $miss_sign_cut = $attendance['miss_sign_cut'];
                    } else {
                        $miss_sign_cut = config('companyRules.miss_sign_cut');
                    }
                    $basicSalary['repair_miss_card_cut'] += $miss_sign_cut * $attendance['miss_sign_times'];
                    $basicSalary['info'] .= "缺签卡" . $attendance['miss_sign_times'] . '次，每次扣款' . $miss_sign_cut . ',补卡缺卡扣款+' . $miss_sign_cut * $attendance['miss_card_times'] . '合计：' . $basicSalary['repair_miss_card_cut'] . ";   ";

                }

                //会议存班 出差天数 考勤备注
                if ($attendance['storage_meeting_time']) {
                    $basicSalary['remarks'] .= '会议存班' . $attendance['storage_meeting_time'] . '小时' . ';';
                }
                if ($attendance['business_travel']) {
                    $basicSalary['remarks'] .= '出差' . $attendance['business_travel'] . '天' . ';';
                }

                $basicSalary['remarks'] .= "考勤备注:" . ($attendance['remarks'] ? $attendance['remarks'] : '无') . ';';

                //计算应发工资合计
                //如果考勤表有正常出勤时间，按出勤时间乘以每小时薪资减去相应扣款算，没有的话按按固定工资合计减去扣款算
                if ($attendance['attendance_days']) {
                    //是否包含实习时间有实习时间
                    if (isset($test_day)) {
                        $normal_days = $attendance['attendance_days'] - $test_day;
                        $basicSalary['info'] .= '实习工资' . $test_day . '天，' . '转正工资' . $normal_days . '天; ';
                        $basicSalary['total_payoff'] += ($salaryPerDays * $test_day + $salaryPerDays / $test_scale * $normal_days);
                        $basicSalary['info'] .= "有考勤天数本月包含实习期,本月实际工资合计=每天实习工资金额" . $salaryPerDays . '*实行工资天数' . $test_day . '+转正工资' . $salaryPerDays / $test_scale . '*转正工资天数' . $normal_days . '=' . $basicSalary['total_payoff'] . ";   ";

                    } else {
                        //不存在实习期，或在实习期情况
                        $basicSalary['total_payoff'] += $salaryPerDays * $attendance['attendance_days'];
                        $basicSalary['info'] .= "有考勤天数,本月实际工资合计=每天工资金额" . $salaryPerDays . '*正常考勤天数' . $attendance['attendance_days'] . '=' . $basicSalary['total_payoff'] . ";   ";
                    }
                }
                //去除考勤部分金额
                if ($basicSalary['total_payoff']) {
                    $total_payoff = $basicSalary['total_payoff'];
                    $basicSalary['total_payoff'] = $total_payoff - $basicSalary['late_cut'] + $basicSalary['sick_allowance'] - $basicSalary['absenteeism_cut'] + $basicSalary['storage_time_cash'] - $basicSalary['repair_miss_card_cut'] + $basicSalary['commission'];

                    $basicSalary['info'] .= "（按考勤天数算）应发工资合计：本月实际工资合计{$total_payoff}-迟到{$basicSalary['late_cut']}-旷工{$basicSalary['absenteeism_cut']}-补缺卡{$basicSalary['repair_miss_card_cut']}+日常存班折现{$basicSalary['storage_time_cash']}+病假补助{$basicSalary['sick_allowance']}+提成合计{$basicSalary['commission']}={$basicSalary['total_payoff']};   ";
                } else {
                    if (!isset($test_day)) {
                        $basicSalary['total_payoff'] = $basicSalary['real_total_fixed_salary'] - $basicSalary['absence_leave_cut'] - $basicSalary['late_cut'] + $basicSalary['sick_allowance'] - $basicSalary['absenteeism_cut'] + $basicSalary['storage_time_cash'] - $basicSalary['repair_miss_card_cut'] + $basicSalary['commission'];
                        $basicSalary['info'] .= "（按实际固定工资合计算）应发工资合计：本月实际固定工资合计{$basicSalary['real_total_fixed_salary']}-事假{$basicSalary['absence_leave_cut']}-迟到{$basicSalary['late_cut']}-旷工{$basicSalary['absenteeism_cut']}-补缺卡{$basicSalary['repair_miss_card_cut']}+日常存班折现{$basicSalary['storage_time_cash']}+病假补助{$basicSalary['sick_allowance']}+提成合计{$basicSalary['commission']}={$basicSalary['total_payoff']};   ";

                    } else {
                        $normal_days = $staff_days - $test_day;
                        $basicSalary['info'] .= '实习工资' . $test_day . '天，' . '转正工资' . $normal_days . '天; ';
                        $basicSalary['total_payoff'] = ($salaryPerDays * $test_day + $salaryPerDays / $test_scale * $normal_days) - $basicSalary['absence_leave_cut'] - $basicSalary['late_cut'] + $basicSalary['sick_allowance'] - $basicSalary['absenteeism_cut'] + $basicSalary['storage_time_cash'] - $basicSalary['repair_miss_card_cut'] + $basicSalary['commission'];
                        $basicSalary['info'] .= "本月包含实习期,本月应发工资合计=每天实习工资金额{$salaryPerDays}*实行工资天数{$test_day}+转正工资" . $salaryPerDays / $test_scale . "*转正工资天数{$normal_days}-事假{$basicSalary['absence_leave_cut']}-迟到{$basicSalary['late_cut']}-旷工{$basicSalary['absenteeism_cut']}-补缺卡{$basicSalary['repair_miss_card_cut']}+日常存班折现{$basicSalary['storage_time_cash']}+病假补助{$basicSalary['sick_allowance']}+提成合计{$basicSalary['commission']}={$basicSalary['total_payoff']};   ";
                    }

                }

                //个户方法处理(有社保工资信息)
                if ($basicSalary['social_security_salary']) {
                    $basicSalary['personal_pay'] = $basicSalary['total_payoff'] - $basicSalary['social_security_salary'];
                    $basicSalary['info'] .= "个户发放=应发工资合计{$basicSalary['total_payoff']}-社保工资{$basicSalary['social_security_salary']}={$basicSalary['personal_pay']};   ";
                } else {
                    $basicSalary['info'] .= "社保工资为空，未计算个户发放工资;   ";
                }
                //如果有税后险后工资算实发工资
                if ($basicSalary['after_tax_insurance_salary']) {
                    $basicSalary['real_pay'] = $basicSalary['personal_pay'] + $basicSalary['after_tax_insurance_salary'];
                    $basicSalary['info'] .= "实发工资=个户发放工资{$basicSalary['personal_pay']}+税后险后工资{$basicSalary['after_tax_insurance_salary']}={$basicSalary['real_pay']};   ";
                } else {
                    $basicSalary['position_level'] = '';
                    $basicSalary['info'] .= "税后险后工资为空，未计算实发工资;   ";
                }

                //需要四舍五入的数据；
                $round = ['merit_salary', 'sick_allowance', 'late_cut', 'absence_leave_cut', 'absenteeism_cut', 'storage_time_cash', 'total_payoff', 'repair_miss_card_cut', 'personal_pay', 'real_pay', 'total_fixed_salary'];

                foreach ($basicSalary as $k => &$v) {
                    if (in_array($k, $round)) {
                        $v = round($v, 2);
                    }
                }

            } else {
                //没有考勤表
                $basicSalary['info'] .= "考勤表没有此员工信息或信息被禁用   ";
            }
            unset($basicSalary['id']);
            if (isset($param['id']) && $param['id'] != '') {
                $basicSalary['id'] = $param['id'];
            }
            $data = $basicSalary;
            return success('生成成功', '', $data);
        } else {
            return error('请选择日期或员工');
        }
    }

    //批量计算员工工资
    public function composeAll(Request $request, Staff $staff, Performance $performance, BasicSalary $basicSalary, Commission $commission, Attendance $attendance, SalaryLog $salaryLog)
    {
        $param = $request->param();
        if (isset($param['salary_time']) && $param['salary_time'] != '') {
            $salary_time = $param['salary_time'];
            $time = strtotime($salary_time);

        } else {
            $time = '';
            error('请选择工资时间', URL_RELOAD);
        }
        $where2 = ['salary_time' => $time];
        $where1 = [];
        $department_id = $param['department_id'] ?? '';
        $staff_id = $param['staff_id'] ?? '';

        if ($department_id != '' && $staff_id != '') {
            $where = ['id' => $staff_id, 'department_id' => $department_id];
            $staff_data = Staff::where($where)->find();
            if (!$staff_data) {
                return json_encode(['code' => 0, 'msg' => "该部门没有此员工"]);
            }
            $where1 = ['st.id' => $staff_id, 'st.department_id' => $department_id, 'st.delete_time' => 0, 'st.status' => 1];
            $where2 = ['staff_id' => $staff_id, 'department_id' => $department_id, 'salary_time' => $time];
        }
        if ($department_id == '' && $staff_id != '') {
            $where = ['id' => $staff_id];
            $staff_data = Staff::where($where)->find();
            if (!$staff_data) {
                return json_encode(['code' => 0, 'msg' => "该部门没有此员工"]);
            }
            $where1 = ['st.id' => $staff_id, 'st.delete_time' => 0, 'st.status' => 1];
            $where2 = ['staff_id' => $staff_id, 'salary_time' => $time];
        }

        if ($department_id != '' && $staff_id == '') {
            $where1 = ['st.department_id' => $department_id, 'st.delete_time' => 0, 'st.status' => 1];
            $where2 = ['department_id' => $department_id, 'salary_time' => $time];
        }
        if ($department_id == '' && $staff_id == '') {
            $where1 = ['st.delete_time' => 0, 'st.status' => 1];
            $where2 = ['salary_time' => $time];
        }

        //确定插入或更新
        $salary_data = SalaryLog::where($where2)->column('staff_id', 'id');
        $datas = Db::table('staff st')
            ->join('department de', 'st.department_id=de.id and de.delete_time=0 ', 'left')
            ->join('attendance at', 'st.id=at.staff_id and at.delete_time=0 and at.status=1 and  at.attendance_time=' . $time . '', 'left')
            ->join('commission co', 'st.id=co.staff_id and commission_time=' . $time . ' and co.delete_time=0 and co.status=1', 'left')
            ->join('performance pe', 'st.id=pe.staff_id and performance_time=' . $time . ' and pe.delete_time=0 and pe.status=1', 'left')
            ->join('basic_salary bs', 'st.id=bs.staff_id and bs.delete_time=0 and bs.status=1', 'left')
            ->join('insure in', 'st.insure_id=in.id', 'left')->field(
                '
                st.id as staff_id,
                st.name staff_name,
                st.insure_id,
                st.department_id,
                st.hired_date,
                st.full_salary_date,
                st.full_date,
                st.card_name,
                st.card_num,
                st.days_per_month,
                st.hours_per_day,
                st.status,
                st.delete_time,
                de.name as department_name,
                de.type as department_type,
                de.delete_time,
                at.position_level,
                at.sick_leave,
                at.absence_leave,
                at.absenteeism,
                at.business_travel,
                at.late_times,
                at.storage_time,
                at.storage_meeting_time,
                at.late_time,
                at.is_full,
                at.attendance_days,
                at.repair_card_times,
                at.miss_card_times,
                at.miss_card_cut,
                at.miss_sign_times,
                at.miss_sign_cut,
                at.remarks as attendance_remarks,
                at.delete_time,
                at.status,
                co.total_commission,
                co.status,
                co.remarks as commission_remarks,
                co.delete_time,
                pe.score,
                pe.status,
                pe.remarks as performance_remarks,
                pe.delete_time,
                bs.test_scale,
                bs.basic_salary,
                bs.title_salary,
                bs.manage_salary,
                bs.education_salary,
                bs.nightwork_salary,
                bs.payscale_salary,
                bs.secret_salary,
                bs.overtime_salary,
                bs.fulltime_salary,
                bs.phone_salary,
                bs.housing_salary,
                bs.other_salary,
                bs.total_fixed_salary,
                bs.base_merit_salary,
                bs.social_security_salary,
                bs.deduct_social_money,
                bs.taxable_salary,
                bs.personal_tax,
                bs.after_tax_insurance_salary,
                bs.remarks as basic_salary_remarks,
                bs.status,
                bs.delete_time,
                in.insure,
                in.id as insure_id
            '
            )->where($where1)->order('st.id')->select();
        //请开始你的表演
        $start = date('Y-m-01', $time);
        $end = date('Y-m-d', strtotime("$start +1 month -1 day"));
        $start_time = strtotime($start);
        $end_time = strtotime($end);
        $basicSalary = [];
        $inScore = \config('companyRules.in_department');
        $outScore = \config('companyRules.out_department');
        //补卡第几次开始扣钱
        $repair_times_rule = \config('companyRules.repair_card_times_limit');
        $repair_card_times_hour = \config('companyRules.repair_card_times_hour');//补卡次数达到规定次数一次扣事假小时数
//        $repair_times_max = \config('companyRules.repair_card_times_max');//补卡多少次扣全勤
        //检索迟到情况
        $late_rule_time_money = \config('companyRules.late_rule_time_money');//迟到规则
        $maxkey = count($late_rule_time_money) - 1;
//        $late_times_limit = \config('companyRules.late_times_limit');
        $sickAllowance = \config('companyRules.sick_leave_allowance_base');//病假补助基数
        //区分内职市场扣款
        $in_miss_card_cut = config('companyRules.in_miss_card_cut');
        if ($datas) {
            foreach ($datas as $key => $value) {
                if (in_array((int)$value['staff_id'], $salary_data)) {
                    $basicSalary[$key]['id'] = array_search($value['staff_id'], $salary_data);
                }
                $basicSalary[$key]['remarks'] = '';
                $basicSalary[$key]['info'] = '';
                $basicSalary[$key]['staff_id'] = $value['staff_id'];
                $basicSalary[$key]['department_id'] = $value['department_id'];
                $basicSalary[$key]['insure_id'] = $value['insure_id'];
                $basicSalary[$key]['basic_salary'] = $value['basic_salary'] ?? '';
                $basicSalary[$key]['manage_salary'] = $value['manage_salary'] ?? '';
                $basicSalary[$key]['title_salary'] = $value['title_salary'] ?? '';
                $basicSalary[$key]['nightwork_salary'] = $value['nightwork_salary'] ?? '';
                $basicSalary[$key]['education_salary'] = $value['education_salary'] ?? '';
                $basicSalary[$key]['payscale_salary'] = $value['payscale_salary'] ?? '';
                $basicSalary[$key]['secret_salary'] = $value['secret_salary'] ?? '';
                $basicSalary[$key]['overtime_salary'] = $value['overtime_salary'] ?? '';
                $basicSalary[$key]['fulltime_salary'] = $value['fulltime_salary'] ?? '';
                $basicSalary[$key]['phone_salary'] = $value['phone_salary'] ?? '';
                $basicSalary[$key]['housing_salary'] = $value['housing_salary'] ?? '';
                $basicSalary[$key]['other_salary'] = $value['other_salary'] ?? '';
                $basicSalary[$key]['total_fixed_salary'] = $value['total_fixed_salary'] ?? '';
                $basicSalary[$key]['base_merit_salary'] = $value['base_merit_salary'] ?? '';
                $basicSalary[$key]['social_security_salary'] = $value['social_security_salary'] ?? '';
                $basicSalary[$key]['deduct_social_money'] = $value['deduct_social_money'] ?? '';
                $basicSalary[$key]['taxable_salary'] = $value['taxable_salary'] ?? "";
                $basicSalary[$key]['personal_tax'] = $value['personal_tax'] ?? '';
                $basicSalary[$key]['after_tax_insurance_salary'] = $value['after_tax_insurance_salary'] ?? '';
                $basicSalary[$key]['remarks'] .= $value['basic_salary_remarks'] . $value['attendance_remarks'] . $value['commission_remarks'] . $value['performance_remarks'];
                $basicSalary[$key]['status'] = $value['status'] ?? 1;
                $basicSalary[$key]['create_time'] = $_SERVER['REQUEST_TIME'];
                $basicSalary[$key]['update_time'] = $_SERVER['REQUEST_TIME'];
                $basicSalary[$key]['delete_time'] = 0;
                $basicSalary[$key]['card_name'] = $value['card_name'] ?? '';
                $basicSalary[$key]['card_num'] = $value['card_num'] ?? '';
                $basicSalary[$key]['salary_time'] = $param['salary_time'];
                $basicSalary[$key]['position_level'] = $value['position_level'] ?? '';
                //是否转正判断
                $full_salary_time = strtotime($value['full_salary_date'] ?? '0000-00-00');//转正时间为空默认没有试用期
                $full_time = strtotime($value['full_date']);

                $flag = 1;
                //在实习期
                if ($full_salary_time >= $end_time) {
                    $flag = $value['test_scale'] ?? 1;//工资基本表实习工资比例
                    $basicSalary[$key]['info'] .= '在实习期';
                }
                //不在实习期
                if ($full_salary_time < $start_time) {
                    $flag = 1;
                }
                //包含实习期
                if ($full_salary_time < $end_time && $full_salary_time >= $start_time) {
                    $flag = $value['test_scale'] ?? 1;//工资基本表实习工资比例
                    $test_day = date('d', $full_salary_time);
                    $end_day = date('d', $end_time);
                    $normal_day = $end_day - $test_day;
                    $basicSalary[$key]['info'] .= "有实习工资" . $test_day . '天 ; ';
                }
                //当月转正
                if ($full_time < $end_time && $full_time >= $start_time) {
                    $basicSalary[$key]['info'] .= '转正;';
                }
                $salaryPerHouse = 0;//员工每小时工资（动态绩效+固定部分）/24/8;
                $full_money = 0;//默认不扣全勤奖
                //提成数据
                $basicSalary[$key]['commission'] = $value['total_commission'] ?? 0;
                $basicSalary[$key]['info'] .= "提成：{$value['total_commission']}";
                if (!$value['basic_salary'] && !$value['total_fixed_salary'] && !$value['base_merit_salary']) {
                    $basicSalary[$key]['info'] .= '此员工没有基本工资或被禁用;';
                    continue;
                }
                //绩效数据处理
                $score = $value['score'];
                //是否有绩效数据
                if (isset($score)) {
                    if ($value['department_type'] == 1) {
                        $score = $score >= $inScore ? $inScore : $value['score'];
                    } elseif ($value['department_type'] == 2) {
                        $score = $score >= $outScore ? $outScore : $value['score'];
                    }
                    //市场一部单独处理
                    $departName = $value['department_name'];
                    $hiredDate = $value['hired_date'];
                    $date = date('Y-m-d', $time);
                    $hiredDate = str_replace('-', '', $hiredDate);
                    $date = str_replace('-', '', $date);
                    //入职时间
                    $hiredmonth = bcsub($date, $hiredDate, 2) / 100;
                    if (strpos($departName, '市场一部') !== false && $score < 60 && $hiredmonth > 6) {
                        //入职超过六个月
                        $basicSalary[$key]['real_total_fixed_salary'] = $value['total_fixed_salary'] * $score / 100;
                        $basicSalary[$key]['merit_salary'] = '';
                        $basicSalary[$key]['info'] .= "市场一部入职6个月以上绩效60分一下,实际固定工资合计=固定工资合计（包含绩效）{$value['total_fixed_salary']}*绩效得分{$score}/100={$basicSalary[$key]['real_total_fixed_salary']};   ";
                    } else {
                        $basicSalary[$key]['merit_salary'] = $value['base_merit_salary'] * $score / 100;
                        $total_fixed_salary = $value['total_fixed_salary'];
                        $basicSalary[$key]['real_total_fixed_salary'] = ($total_fixed_salary - $value['base_merit_salary'] + $basicSalary[$key]['merit_salary']) * $flag;//实习相应折扣
                        $basicSalary[$key]['info'] .= "绩效工资=绩效工资基数{$value['base_merit_salary']}*绩效评分{$score}={$basicSalary[$key]['merit_salary']}; ";

                        $basicSalary[$key]['info'] .= "实际固定工资为固定工资（{$value['total_fixed_salary']}-固定绩效{$value['base_merit_salary']}+实际绩效{$basicSalary[$key]['merit_salary']}）*{$flag}(是否实习) ={$basicSalary[$key]['real_total_fixed_salary']}; ";
                    }
                } else {
                    //无绩效按固定绩效算
                    //没有绩效表的暂时按固定绩效算
                    $basicSalary[$key]['merit_salary'] = $value['base_merit_salary'];
                    $basicSalary[$key]['real_total_fixed_salary'] = $value['total_fixed_salary'] * $flag;//实习相应折扣。
                    $basicSalary[$key]['info'] .= "没有{$param['salary_time']}绩效信息，实际固定工资=固定工资为{$basicSalary[$key]['real_total_fixed_salary']}; ";
                    $basicSalary[$key]['info'] .= "没有{$param['salary_time']}绩效信息，绩效工资=绩效基本工资{$value['base_merit_salary']};   ";
                }

                $basicSalary[$key]['sick_allowance'] = 0;//病假补助
                $basicSalary[$key]['late_cut'] = 0;//迟到扣款
                $basicSalary[$key]['absence_leave_cut'] = 0;//事假
                $basicSalary[$key]['absenteeism_cut'] = 0;//旷工
                $basicSalary[$key]['storage_time_cash'] = 0;//加班储存
                $basicSalary[$key]['total_payoff'] = 0; //应发工资合计
                $basicSalary[$key]['repair_miss_card_cut'] = 0;//补卡缺卡扣除
                $basicSalary[$key]['personal_pay'] = 0; //个户发放
                $basicSalary[$key]['real_pay'] = 0;//实发工资
                //未处理
                $basicSalary[$key]['travel_allowance'] = 0;//出差补助
                $basicSalary[$key]['live_commission'] = 0;//直播提成
                $basicSalary[$key]['bonus_penalty'] = 0;//奖惩
                $basicSalary[$key]['other'] = 0;//其他
                $basicSalary[$key]['cut_cash'] = 0;//扣款
                //员工工作天数、每天工作小时
                $staff_days = $value['days_per_month'];
                $staff_hours = $value['hours_per_day'];
                //扣全勤的情况  迟到情况处理：达到三次扣全勤奖
                if (isset($value['is_full']) && !$value['is_full']) {
                    $full_money = 200;
                    $basicSalary[$key]['fulltime_salary'] = 0;
                    $real_total_fixed_salary = $basicSalary[$key]['real_total_fixed_salary'];
                    $basicSalary[$key]['real_total_fixed_salary'] = $real_total_fixed_salary - 200;
                    //缺勤时时薪计算先减200；
                    $salaryPerDays = $basicSalary[$key]['real_total_fixed_salary'] / $staff_days;
                    $salaryPerHouse = $basicSalary[$key]['real_total_fixed_salary'] / $staff_days / $staff_hours;
                    //计算存班时薪
                    $salaryPerHouse2 = $real_total_fixed_salary / $staff_days / $staff_hours;
                    $basicSalary[$key]['info'] .= "实际固定工资=固定工资{$real_total_fixed_salary}-全勤200={$basicSalary[$key]['real_total_fixed_salary']}，每小时工资=实际固定工资（包含当月绩效绩效）" . $basicSalary[$key]['real_total_fixed_salary'] . "/$staff_days/$staff_hours={$salaryPerHouse};   ";
                } else {
                    $salaryPerDays = $basicSalary[$key]['real_total_fixed_salary'] / $staff_days;
                    $salaryPerHouse = $basicSalary[$key]['real_total_fixed_salary'] / $staff_days / $staff_hours;
                    $salaryPerHouse2 = $basicSalary[$key]['real_total_fixed_salary'] / $staff_days / $staff_hours;
                }

                if ($value['late_time']) {
                    $late_time = json_decode($value['late_time']);
                    foreach ($late_time as $keys => $values) {
                        foreach ($late_rule_time_money as $k => $v) {
                            if ($values <= $v['time']) {
                                //大于一小时按事假
                                if ($k < $maxkey) {
                                    $basicSalary[$key]['late_cut'] += $v['money'];
                                    $basicSalary[$key]['info'] .= "迟到扣款+{$v['money']}合计：{$basicSalary[$key]['late_cut']};   ";
                                } else {
                                    //已经扣了全勤奖的情况

                                    //半小时为节点
                                    $hour1 = floor($values / 60);
                                    $mod = $values % 60;
                                    if ($mod <= 30) {
                                        $hour = $hour1 + 0.5;
                                    } else {
                                        $hour = $hour1 + 1;
                                    }
                                    $basicSalary[$key]['late_cut'] += $salaryPerHouse * $hour;
                                    $basicSalary[$key]['info'] .= "迟到时间超过一个小时事假扣款，迟到扣款+{$salaryPerHouse}*{$hour}迟到扣款合计{$basicSalary['late_cut']};   ";
                                }

                                break;
                            }
                        }
                    }
                }
                //病假部分处理
                if ($value['sick_leave']) {
                    //病假补助2050*0.8/24/8
                    $basicSalary[$key]['sick_allowance'] = round($sickAllowance * 0.8 / $staff_hours / $staff_days * $value['sick_leave'], 2);
                    $basicSalary[$key]['info'] .= "病假补助=基数{$sickAllowance}*0.8/$staff_days/$staff_hours={$basicSalary[$key]['sick_allowance']};   ";
                    //事假扣款（病假部分）
                    $basicSalary[$key]['absence_leave_cut'] = $salaryPerHouse * $value['sick_leave'];
                    $basicSalary[$key]['info'] .= "事假扣款（病假部分）=每小时工资{$salaryPerHouse}*病假{$value['sick_leave']}小时={$basicSalary[$key]['absence_leave_cut']};   ";
                }

                //事假部分处理
                if ($value['absence_leave']) {
                    $basicSalary[$key]['absence_leave_cut'] += $salaryPerHouse * $value['absence_leave'];
                    $basicSalary[$key]['info'] .= "事假扣款（包含病假部分)=每小时工资{$salaryPerHouse}*事假{$value['absence_leave']}小时+病假扣款={$basicSalary[$key]['absence_leave_cut']};   ";
                }

                //旷工部分处理
                if ($value['absenteeism']) {
                    $basicSalary[$key]['absenteeism_cut'] = $salaryPerHouse * $value['absenteeism'] * 3;
                    $basicSalary[$key]['info'] .= "旷工扣款=每小时工资{$salaryPerHouse}*3*旷工{$value['absenteeism']}小时={$basicSalary[$key]['absenteeism_cut']};   ";
                }

                //存班情况处理（存班按不扣全勤奖计算）
                if ($value['storage_time']) {
                    $basicSalary[$key]['storage_time_cash'] = $salaryPerHouse2 * $value['storage_time'];
                    $basicSalary[$key]['info'] .= "存班折现=存班时间（时）{$value['storage_time']}*（未减全勤）每小时工资{$salaryPerHouse2}={$basicSalary[$key]['storage_time_cash']};   ";
                }

                if ($value['repair_card_times'] >= $repair_times_rule) {
                    $repair_times_hour = ($value['repair_card_times'] + 1 - $repair_times_rule) * $repair_card_times_hour;
                    $basicSalary[$key]['repair_miss_card_cut'] += $salaryPerHouse * $repair_times_hour;
                    $basicSalary[$key]['info'] .= "补卡{$value['repair_card_times']}次达到或超过规定次数{$repair_times_rule}每超过一次按事假{$repair_card_times_hour}小时计算，补卡扣款{$basicSalary[$key]['repair_miss_card_cut']};   ";
                }


                //缺卡情况缺卡一次按旷工一个小时算
                if ($value['miss_card_times']) {
                    if ($value['department_type'] == 1) {
                        $basicSalary[$key]['repair_miss_card_cut'] += $salaryPerHouse * $in_miss_card_cut * $value['miss_card_times'];
                        $basicSalary[$key]['info'] .= "缺卡" . $value['miss_card_times'] . '次每次按旷工一小时计算，每小时工资' . $salaryPerHouse . "*$in_miss_card_cut*" . '次数' . $value['miss_card_times'] . ',补卡缺卡扣款+' . $salaryPerHouse * 3 * $value['miss_card_times'] . '合计：' . $basicSalary[$key]['repair_miss_card_cut'] . ";   ";
                    }

                    if ($value['department_type']) {
                        if (isset($value['miss_card_cut'])) {
                            $miss_card_cut = $value['miss_card_cut'];
                        } else {
                            $miss_card_cut = config('companyRules.miss_card_cut');
                        }
                        $basicSalary[$key]['repair_miss_card_cut'] += $miss_card_cut * $value['miss_card_times'];
                        $basicSalary[$key]['info'] .= "缺卡" . $value['miss_card_times'] . '次每次扣款' . $miss_card_cut . ',补卡缺卡扣款+' . $miss_card_cut * $value['miss_card_times'] . '合计：' . $basicSalary[$key]['repair_miss_card_cut'] . ";   ";
                    }
                }
                //市场员工缺签到扣款处理
                if ($value['miss_sign_times'] && $value['department_type'] == 2) {

                    if (isset($value['miss_sign_cut'])) {
                        $miss_sign_cut = $value['miss_sign_cut'];
                    } else {
                        $miss_sign_cut = config('companyRules.miss_sign_cut');
                    }
                    $basicSalary[$key]['repair_miss_card_cut'] += $miss_sign_cut * $value['miss_sign_times'];
                    $basicSalary[$key]['info'] .= "缺签卡" . $value['miss_sign_times'] . '次，每次扣款' . $miss_sign_cut . ',补卡缺卡扣款+' . $miss_sign_cut * $value['miss_card_times'] . '合计：' . $basicSalary[$key]['repair_miss_card_cut'] . ";   ";

                }

                //会议存班 出差天数 考勤备注
                if ($value['storage_meeting_time']) {
                    $basicSalary[$key]['remarks'] .= '会议存班' . $value['storage_meeting_time'] . '小时' . '未处理;';
                }
                if ($value['business_travel']) {
                    $basicSalary[$key]['remarks'] .= '出差' . $value['business_travel'] . '天' . '未处理;';
                }


                //计算应发工资合计
                //如果考勤表有正常出勤时间，按出勤时间乘以每小时薪资减去相应扣款算，没有的话按按固定工资合计减去扣款算
                if ($value['attendance_days']) {
                    //是否包含实习时间有实习时间
                    if (isset($test_day)) {
                        $normal_days = $value['attendance_days'] - $test_day;
                        $basicSalary[$key]['info'] .= '实习工资' . $test_day . '天，' . '转正工资' . $normal_days . '天; ';
                        $basicSalary[$key]['total_payoff'] += ($salaryPerDays * $test_day + $salaryPerDays / $value['test_scale'] * $normal_days);
                        $basicSalary[$key]['info'] .= "有考勤天数本月包含实习期,本月实际工资合计=每天实习工资金额" . $salaryPerDays . '*实行工资天数' . $test_day . '+转正工资' . $salaryPerDays / $value['test_scale'] . '*转正工资天数' . $normal_days . '=' . $basicSalary[$key]['total_payoff'] . ";   ";

                    } else {
                        //不存在实习期，或在实习期情况
                        $basicSalary[$key]['total_payoff'] += $salaryPerDays * $value['attendance_days'];
                        $basicSalary[$key]['info'] .= "有考勤天数,本月实际工资合计=每天工资金额" . $salaryPerDays . '*正常考勤天数' . $value['attendance_days'] . '=' . $basicSalary[$key]['total_payoff'] . ";   ";
                    }
                }
                //去除考勤部分金额
                if ($basicSalary[$key]['total_payoff']) {
                    $total_payoff = $basicSalary[$key]['total_payoff'];

                    $basicSalary[$key]['total_payoff'] = $basicSalary[$key]['total_payoff'] - $basicSalary[$key]['late_cut'] + $basicSalary[$key]['sick_allowance'] - $basicSalary[$key]['absenteeism_cut'] + $basicSalary[$key]['storage_time_cash'] - $basicSalary[$key]['repair_miss_card_cut'] + $basicSalary[$key]['commission'];
                    $basicSalary[$key]['info'] .= "（按考勤天数算）应发工资合计：本月实际工资合计{$total_payoff}-迟到{$basicSalary[$key]['late_cut']}-旷工{$basicSalary[$key]['absenteeism_cut']}-补缺卡{$basicSalary[$key]['repair_miss_card_cut']}+日常存班折现{$basicSalary[$key]['storage_time_cash']}+病假补助{$basicSalary[$key]['sick_allowance']}+提成合计{$basicSalary[$key]['commission']}={$basicSalary[$key]['total_payoff']};   ";
                } else {
                    if (!isset($test_day)) {
                        $basicSalary[$key]['total_payoff'] = $basicSalary[$key]['real_total_fixed_salary'] - $basicSalary[$key]['absence_leave_cut'] - $basicSalary[$key]['late_cut'] + $basicSalary[$key]['sick_allowance'] - $basicSalary[$key]['absenteeism_cut'] + $basicSalary[$key]['storage_time_cash'] - $basicSalary[$key]['repair_miss_card_cut'] + $basicSalary[$key]['commission'];
                        $basicSalary[$key]['info'] .= "（按实际固定工资合计算）应发工资合计：本月实际固定工资合计{$basicSalary[$key]['real_total_fixed_salary']}-事假{$basicSalary[$key]['absence_leave_cut']}-迟到{$basicSalary[$key]['late_cut']}-旷工{$basicSalary[$key]['absenteeism_cut']}-补缺卡{$basicSalary[$key]['repair_miss_card_cut']}+日常存班折现{$basicSalary[$key]['storage_time_cash']}+病假补助{$basicSalary[$key]['sick_allowance']}+提成合计{$basicSalary[$key]['commission']}={$basicSalary[$key]['total_payoff']};   ";

                    } else {
                        $normal_days = $staff_days - $test_day;
                        $basicSalary[$key]['info'] .= '实习工资' . $test_day . '天，' . '转正工资' . $normal_days . '天; ';
                        $basicSalary[$key]['total_payoff'] = ($salaryPerDays * $test_day + $salaryPerDays / $value['test_scale'] * $normal_days) - $basicSalary[$key]['absence_leave_cut'] - $basicSalary[$key]['late_cut'] + $basicSalary[$key]['sick_allowance'] - $basicSalary[$key]['absenteeism_cut'] + $basicSalary[$key]['storage_time_cash'] - $basicSalary[$key]['repair_miss_card_cut'] + $basicSalary[$key]['commission'];
                        $basicSalary[$key]['info'] .= "本月包含实习期,本月应发工资合计=每天实习工资金额{$salaryPerDays}*实行工资天数{$test_day}+转正工资" . $salaryPerDays / $value['test_scale'] . "*转正工资天数{$normal_days}-事假{$basicSalary[$key]['absence_leave_cut']}-迟到{$basicSalary[$key]['late_cut']}-旷工{$basicSalary[$key]['absenteeism_cut']}-补缺卡{$basicSalary[$key]['repair_miss_card_cut']}+日常存班折现{$basicSalary[$key]['storage_time_cash']}+病假补助{$basicSalary[$key]['sick_allowance']}+提成合计{$basicSalary[$key]['commission']}={$basicSalary[$key]['total_payoff']};   ";
                    }

                }
                unset($test_day);
                //个户方法处理(有社保工资信息)
                if ($value['social_security_salary']) {
                    $basicSalary[$key]['personal_pay'] = $basicSalary[$key]['total_payoff'] - $value['social_security_salary'];
                    $basicSalary[$key]['info'] .= "个户发放=应发工资合计{$basicSalary[$key]['total_payoff']}-社保工资{$value['social_security_salary']}={$basicSalary[$key]['personal_pay']};   ";
                } else {
                    $basicSalary[$key]['info'] .= "社保工资为空，未计算个户发放工资;   ";
                }
                //如果有税后险后工资算实发工资
                if ($value['after_tax_insurance_salary']) {
                    $basicSalary[$key]['real_pay'] = $basicSalary[$key]['personal_pay'] + $value['after_tax_insurance_salary'];
                    $basicSalary[$key]['info'] .= "实发工资=个户发放工资{$basicSalary[$key]['personal_pay']}+税后险后工资{$value['after_tax_insurance_salary']}={$basicSalary[$key]['real_pay']};   ";
                } else {
                    $basicSalary[$key]['info'] .= "税后险后工资为空，未计算实发工资;   ";
                }

                //需要四舍五入的数据；
                $round = ['merit_salary', 'sick_allowance', 'late_cut', 'absence_leave_cut', 'absenteeism_cut', 'storage_time_cash', 'total_payoff', 'repair_miss_card_cut', 'personal_pay', 'real_pay', 'total_fixed_salary'];

                foreach ($basicSalary[$key] as $k => $v) {
                    if (in_array($k, $round)) {
                        $basicSalary[$key][$k] = round($basicSalary[$key][$k], 2);
                    }
                }
            }
            Db::startTrans();
            try {
                $res = $salaryLog->saveAll($basicSalary,true);
                Db::commit();
                return json_encode(['code' => 1, 'msg' => 'success']);

            } catch (\Exception $e) {
                Db::rollback();
                return json_encode(['code' => 0, 'msg' => '计算失败']);
            }

        } else {
            return json_encode(['code' => 0, 'msg' => '没有信息']);
        }

    }


    //提成考勤提成信息展示
    public function view(Request $request, Commission $commission, BasicSalary $basicSalary, Performance $performance, Attendance $attendance)
    {
        $params = $request->param();
        $basicSalaryArr = ['id' => '主键', 'staff_id' => '员工id', 'staff' => 'staff', 'basic_salary' => '基本工资', 'manage_salary' => '管理工资', 'title_salary' => '职称工资', 'education_salary' => '学历津贴', 'nightwork_salary' => '夜班津贴', 'payscale_salary' => '薪级工资', 'secret_salary' => '保密工资', 'overtime_salary' => "加班工资", 'fulltime_salary' => '全勤奖', 'phone_salary' => '通讯补贴', 'housing_salary' => '住房补贴', 'other_salary' => '其他', 'total_fixed_salary' => '固定工资合计', 'base_merit_salary' => '绩效基数', 'social_security_salary' => '社保工资', 'deduct_social_money' => '社保扣除', 'taxable_salary' => '计税工资', 'personal_tax' => '个税', 'after_tax_insurance_salary' => '税后险后工资', 'card_name' => '姓名', 'card_num' => '卡号', 'file' => '文件', 'status' => '状态', 'update_time' => '修改时间', 'remarks' => '备注'];
        $commissionArr = ['id' => '主键', 'staff_id' => '员工id', 'staff' => 'staff', 'completion' => '业绩完成', 'department_commission' => '部门提成', 'hos_wax_subsidy' => '医院打蜡补助', 'recommend_bonus' => '推荐奖金', 'reissue_commission' => '补发提成', 'help_commission' => '助成交提成', 'expert_commission' => '专家提成', 'meeting_subsidy' => "会场补助", 'total_commission' => '提成合计', 'remarks' => '备注', 'status' => '状态', 'file' => '文件', 'update_time' => '修改时间', 'commission_time' => '提成时间'];
        $attendanceArr = ['id' => '主键', 'staff_id' => '员工id', 'staff' => 'staff', 'sick_leave' => '病假时间（时）', 'absence_leave' => '事假时间（时）', 'absenteeism' => '旷工时间（时）', 'business_travel' => '出差时间（天）', 'late_times' => '迟到次数', 'storage_time' => '日常存班时间（小时）', 'storage_meeting_time' => '会议存班时间（时）', 'late_time' => "迟到情况", 'is_full' => '是否全勤', 'is_new' => '是否有实习期', 'attendance_days' => '正常出勤天数', 'attendance_test_days' => '实习出勤天数', 'repair_card_times' => '补卡次数', 'miss_card_times' => '缺卡次数', 'remarks' => '备注', 'file' => '文件', 'attendance_time' => '考勤时间', 'update_time' => '修改时间', 'status' => '状态'];
        $performanceArr = ['id' => '主键', 'staff_id' => '员工id', 'staff' => 'staff', 'score' => '绩效得分', 'bonus' => '奖金', 'performance_time' => '绩效日期', 'remarks' => '备注', 'status' => '状态', 'file' => '文件', 'update_time' => '修改时间'];
        if (!empty($params['id']) && !empty($params['opea'])) {
            $model = $params['opea'];
            $timeStr = $params['opea'] . '_time';
            $time = strtotime($params['time']);
            if ($model != "basicSalary") {
                $data1 = $$model->where(['staff_id' => $params['id'], $timeStr => $time])->with('staff')->find();
            } else {
                $data1 = $$model->where(['staff_id' => $params['id']])->with('staff')->find();
            }
            $data = [];
            if ($data1) {
                $dataArr = $data1->toArray();
                $stri = $model . "Arr";
                $arr = $$stri;
                foreach ($dataArr as $key => $value) {
                    if (array_key_exists($key, $arr)) {
                        $data[$arr[$key]] = $value;
                    }
                }
            } else {
                $data = [];
            }
            $this->assign(
                ['data' => $data]
            );
            return $this->fetch();
        } else {
            $this->assign(['data' => []]);
            return $this->fetch();
        }

    }
}
